package org.jsola.hr.provider.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jsola.admin.dto.SubjectFunctionDTO;
import org.jsola.admin.entity.FunctionModularDO;
import org.jsola.admin.service.IFunctionModularService;
import org.jsola.admin.vo.AllPermissionVO;
import org.jsola.admin.vo.FunctionModularVO;
import org.jsola.common.TreeKit;
import org.jsola.core.entity.BaseTreeDO;
import org.jsola.core.vo.BaseTreeVO;
import org.jsola.hr.provider.IModularProviderService;
import org.jsola.hr.provider.IPermissionProviderService;
import org.jsola.hr.query.HrFunctionModularQueryDTO;
import org.jsola.hr.service.IHrPermissionService;
import org.jsola.permission.entity.PermissionDO;
import org.jsola.user.core.TokenUser;
import org.jsola.user.core.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ModularProviderServiceImpl implements IModularProviderService {

    @Autowired
    IFunctionModularService functionModularService;

    @Autowired
    private IHrPermissionService hrPermissionService;

    @Autowired
    private IPermissionProviderService permissionProviderService;

    @Override
    public List<FunctionModularVO> listByApp(HrFunctionModularQueryDTO hrFunctionModularQueryDTO) {
        List<FunctionModularDO> result = new ArrayList<>();
        TokenUser tokenUser = UserContext.getUser();
        // 获取功能模块
        // 默认查租户
        SubjectFunctionDTO queryDTO = new SubjectFunctionDTO();
        queryDTO.setCode(hrFunctionModularQueryDTO.getCode());
        // 只查询不隐藏的
        queryDTO.setIsHide("1");
        queryDTO.setSiteId(tokenUser.getSiteId());
        List<FunctionModularDO> siteList = functionModularService.selectByAppCodeSiteId(queryDTO, null);
        if (!CollectionUtils.isEmpty(siteList)) {
            result.addAll(siteList);
        } else {
            //如果租户也没配置，就查询系统默认的
            queryDTO.setSiteId("default");
            List<FunctionModularDO> defaultList = functionModularService.selectByAppCodeSiteId(queryDTO, null);
            if (!CollectionUtils.isEmpty(defaultList)) {
                result.addAll(defaultList);
            }
        }

        // TODO 用工单位设置覆盖

        // TODO 个人设置覆盖


        // 定义返回对象
        List<FunctionModularVO> functionModularVOList = Collections.emptyList();

        // 如果查询到功能模块，与权限字符串做匹配，过滤掉没有权限的功能
        if (!CollectionUtils.isEmpty(result)) {
            // 排序
            Collections.sort(result, Comparator.comparing(BaseTreeDO::getSort));
            //平铺转树
            result = TreeKit.toTreeList(result);

            // 获得权限串
            AllPermissionVO allPermissionVO = hrPermissionService.listUserPermission(hrFunctionModularQueryDTO.getCompanyId(), tokenUser);
            List<String> permissionStr = allPermissionVO.getPermissionStringList();
            // 权限过滤
            permissionFilter(permissionStr, result);

            // 多级DO转VO
            functionModularVOList = convertTreeVOList(result, FunctionModularVO.class);
        }

        return functionModularVOList;
    }

    /**
     * 根据原子权限过滤无权限的目录
     *
     * @param permissionStr 原子权限字符串列表
     * @param modularDOList 功能权限树
     */
    private void permissionFilter(List<String> permissionStr, List<? extends BaseTreeDO> modularDOList) {

        // 倒序循环列表 避免由删除导致的数组越界
        for (int i = modularDOList.size() - 1; i >= 0; i--) {

            // 类型转换
            FunctionModularDO modularDO = (FunctionModularDO) modularDOList.get(i);

            // 如果有子集 先递归判断子集
            if (!CollectionUtils.isEmpty(modularDO.getChildList())) {
                permissionFilter(permissionStr, modularDO.getChildList());
            }

            // 获取当前菜单权限ID
            Integer modularPermissionId = modularDO.getFunctionPermissionId();

            // 临时变量 储存权限字符
            Optional<String> temp = Optional.empty();

            if (ObjectUtils.isNotEmpty(modularPermissionId)) {
                // 根据id查询原子权限
                PermissionDO permissionDO = permissionProviderService.selectDOById(Long.valueOf(modularPermissionId));
                if (ObjectUtils.isNotEmpty(permissionDO)) {
                    // 生成权限字符串
                    temp = permissionProviderService.getPermissionStringList(Collections.singletonList(permissionDO)).stream().findFirst();
                }
            }

            // 当前权限字符串 如果没有设置为空字符串
            String modularPermissionStr = temp.orElse(StringUtils.EMPTY);

            // 递归完成后 如果子项为空判断权限字符串是否匹配
            if (permissionStr == null || (CollectionUtils.isEmpty(modularDO.getChildList()) && permissionStr.stream().noneMatch(e -> StringUtils.equals(e, modularPermissionStr)))) {
                // 移除当前对象
                modularDOList.remove(i);
            }
        }
    }

    /**
     * TreeDOList递归转TreeVOList
     *
     * @param sourceDOList 功能权限树DOList
     * @return
     */
    private <T extends BaseTreeVO> List<T> convertTreeVOList(List<? extends BaseTreeDO> sourceDOList, Class<T> clazz) {
        if (ObjectUtils.isEmpty(sourceDOList)) {
            return Collections.emptyList();
        }
        return sourceDOList.parallelStream()
                .map(sourceDO -> {
                    T vo = sourceDO.to(clazz);
                    List<T> childList = convertTreeVOList(sourceDO.getChildList(), clazz);
                    vo.setChildList(childList);
                    return vo;
                }).collect(Collectors.toList());
    }
}
